package com.l2jserver.gameserver.communitybbs.Manager.Casino.BlackJack;

import java.util.List;
import java.util.StringTokenizer;

import javolution.util.FastList;

import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.ImagesTables;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.clientpackets.Say2;
import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
import com.l2jserver.util.Rnd;

/**
 * @author fissban
 */
public class NewGame
{
	L2PcInstance _player;
	private String _imgCartasFormatHtmlPlayer;
	private String _imgCartasFormatHtmlBanca;
	
	// @formatter:off
	private final String[] _signos =
	{
		"trebol","pique","corazon","diamante"
	};
	private final String[] _numeros =
	{
		"A","2","3","4","5","6","7","8","10","J","Q","K",
	};
	// @formatter:on
	
	/** Apuesta del jugador */
	private int _apuesta;
	
	/** llevamos un contador sobre la cant de cartas q han salido para cada jugador */
	private final int _contadorCartasPlayer;
	private final int _contadorCartasBanca;
	
	/** llevamos la sumatoria de las cartas de cada jugador */
	private int _cartasPlayer;
	private int _cartasBanca;
	
	/** usado para el generar un mazo de forma ordenada */
	private final List<String> _mazo;
	
	/** usado para llevar control de las cartas q van saliendo del mazo apra evitar q se repitan */
	private final List<String> _cartasOff;
	
	private boolean _betDoble;
	
	public NewGame(L2PcInstance player, int apuesta)
	{
		_imgCartasFormatHtmlPlayer = "";
		_imgCartasFormatHtmlBanca = "";
		_contadorCartasPlayer = 0;
		_contadorCartasBanca = 0;
		_cartasPlayer = 0;
		_cartasBanca = 0;
		_betDoble = false;
		_mazo = new FastList<>();
		_cartasOff = new FastList<>();
		_apuesta = apuesta;
		_player = player;
	}
	
	/**
	 * Creamos el mazo con 7 barajes de cartas de forma ordenada
	 */
	private void crearMazo()
	{
		for (int cont = 1; cont <= 8; cont++) // FIXME 1 para cont ??
		{
			for (String signo : _signos)
			{
				for (String numero : _numeros)
				{
					_mazo.add(numero + " " + signo + " " + cont);
				}
			}
		}
	}
	
	/**
	 * Repartimos una carta al azar que no halla sido ya jugada
	 * @param jugador
	 */
	public void repartirCarta(String jugador)
	{
		// TODO tiene q haber una mejor forma de elegir una carta al azar q no halla salido ya!
		boolean condicion = true;
		String carta = "";
		
		// El mazo se crea si el mismo esta vacio
		if (_mazo.isEmpty())
		{
			crearMazo();
		}
		// Si salieron mas de 348 cartas volvemos a crear los mazos dejando de esta forma 100 cartas sin ser descubiertas.
		if (_cartasOff.size() > 348)
		{
			_mazo.clear();
			_cartasOff.clear();
			crearMazo();
		}
		while (condicion)
		{
			carta = _mazo.get(Rnd.get(_mazo.size()));
			
			if (_cartasOff.contains(carta))
			{
				condicion = true;
			}
			else
			{
				condicion = false;
			}
		}
		_cartasOff.add(carta);
		
		sumatoriaCartas(carta, jugador);
		imagenCarta(carta, jugador);
	}
	
	private void imagenCarta(String carta, String jugador)
	{
		int imagen = 9000;
		StringTokenizer st = new StringTokenizer(carta, " ");
		
		String valor = st.nextToken();
		String palo = st.nextToken();
		
		switch (valor)
		{
			case "A":
				imagen += 1;
				break;
			case "K":
				imagen += 13;
				break;
			case "Q":
				imagen += 12;
				break;
			case "J":
				imagen += 11;
				break;
			default:
				imagen += Integer.parseInt(valor);
				break;
		}
		
		switch (palo)
		{
			case "trebol":
				imagen += 20;
				break;
			case "pique":
				imagen += 40;
				break;
			case "corazon":
				imagen += 60;
				break;
			case "diamante":
				imagen += 80;
				break;
		}
		
		switch (jugador)
		{
			case "player":
				_imgCartasFormatHtmlPlayer += "<td align=center valign=center><img src=Crest.crest_" + Config.SERVER_ID + "_" + imagen + " width=64 height=64></td>";
				break;
			case "banca":
				_imgCartasFormatHtmlBanca += "<td align=center valign=center><img src=Crest.crest_" + Config.SERVER_ID + "_" + imagen + " width=64 height=64></td>";
				break;
		}
		
		ImagesTables.getInstance().sendImage(_player, imagen);
	}
	
	/**
	 * Asignamos un valor a la carta y se lo asignamos a un jugador
	 * @param carta
	 * @param jugador
	 */
	private void sumatoriaCartas(String carta, String jugador)
	{
		StringTokenizer st = new StringTokenizer(carta, " ");
		
		int suma = 0;
		
		String valor = st.nextToken();
		switch (valor)
		{
			case "A":
				if ((suma + 11) > 21)
				{
					suma += 1;
				}
				else
				{
					suma += 11;
				}
				break;
			case "K":
				suma += 10;
				break;
			case "Q":
				suma += 10;
				break;
			case "J":
				suma += 10;
				break;
			default:
				suma += Integer.parseInt(valor);
				break;
		}
		
		switch (jugador)
		{
			case "player":
				_cartasPlayer += suma;
				break;
			case "banca":
				_cartasBanca += suma;
				break;
		}
	}
	
	/**
	 * player, banca, empate
	 */
	public void winner()
	{
		String resultado = "";
		
		if (_cartasBanca > 21)
		{
			resultado = "player";
		}
		else if (_cartasPlayer > 21)
		{
			resultado = "banca";
		}
		else if (_cartasPlayer > _cartasBanca)
		{
			resultado = "player";
		}
		else if (_cartasPlayer < _cartasBanca)
		{
			resultado = "banca";
		}
		else if (getBlackJackPlayer() && getBlackJackBanca())
		{
			// tenemos en cuenta si ambos tienen 21...uno o el otro podrian tener BlackJack
			resultado = "empate";
		}
		else if (getBlackJackPlayer())
		{
			resultado = "player";
		}
		else if (getBlackJackBanca())
		{
			resultado = "banca";
		}
		else
		{
			// ninguno de los 2 tienen Black Jack pero tienen 21 ambos
			resultado = "empate";
		}
		
		switch (resultado)
		{
			case "player":
				_player.sendPacket(new CreatureSay(0, Say2.TELL, "[BlackJack]", "WIN!"));
				
				System.out.println("win");
				
				int pago = getApuesta();
				
				if (getBlackJackPlayer())
				{
					_player.addItem("casino pago", Config.ITEM_ID_CASINO_BLACK, pago * 3, _player, false);
				}
				else
				{
					if (getDoble())
					{
						pago *= 4;
					}
					else
					{
						pago *= 2;
					}
					_player.addItem("casino pago", Config.ITEM_ID_CASINO_BLACK, pago, _player, false);
				}
				break;
			case "banca":
				_player.sendPacket(new CreatureSay(0, Say2.TELL, "[BlackJack]", "LOSE!"));
				System.out.println("lose");
				break;
			case "empate":
				_player.sendPacket(new CreatureSay(0, Say2.TELL, "[BlackJack]", "DRAW!"));
				System.out.println("empate");
				_player.addItem("casino pago", Config.ITEM_ID_CASINO_BLACK, getApuesta(), _player, false);
				break;
		
		}
		
	}
	
	// ~------------ METODOS GET and SET ------------~ //
	
	/**
	 * @return apuesta del player
	 */
	public int getApuesta()
	{
		return _apuesta;
	}
	
	/**
	 * @param apuesta del jugador 1 o 2
	 */
	public void setApuesta(int apuesta)
	{
		switch (apuesta)
		{
			case 1:
				_apuesta = Config.BET_BLACK_1;
				break;
			case 2:
				_apuesta = Config.BET_BLACK_2;
				break;
		}
	}
	
	public void setDoble(boolean doble)
	{
		_betDoble = doble;
	}
	
	public boolean getDoble()
	{
		return _betDoble;
	}
	
	/**
	 * @return sumatoria de las cartas del player
	 */
	public int getSumaCartasPlayer()
	{
		return _cartasPlayer;
	}
	
	/**
	 * @return sumatoria de las cartas de la Banca
	 */
	public int getSumaCartasBanca()
	{
		return _cartasBanca;
	}
	
	/**
	 * @return si el player tiene blackJack o no
	 */
	public boolean getBlackJackPlayer()
	{
		if ((_contadorCartasPlayer == 2) && (_cartasPlayer == 21))
		{
			return true;
		}
		return false;
	}
	
	/**
	 * @return si la banca tiene blackJack o no
	 */
	public boolean getBlackJackBanca()
	{
		if ((_contadorCartasBanca == 2) && (_cartasBanca == 21))
		{
			return true;
		}
		return false;
	}
	
	/**
	 * @return las cartas jugadas con formato html
	 */
	public String getCartasFormatHtmlBanca()
	{
		return _imgCartasFormatHtmlBanca;
	}
	
	/**
	 * @return las cartas jugadas con formato html
	 */
	public String getCartasFormatHtmlPlayer()
	{
		return _imgCartasFormatHtmlPlayer;
	}
	
	public int getCountCartsPlayer()
	{
		return _contadorCartasPlayer;
	}
}